package gui.archerDbEditor;

import gui.InformationDisplay;
import gui.addArcherWindow.AddArcherWindow;
import gui.helper.CorrectnessTester;

import java.awt.Color;
import java.sql.SQLException;
import java.util.Observable;
import java.util.Observer;

import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;

import table.models.ArcherDBTableModel;
import core.Constants;
import core.Date;
import core.GuiComponentLabels;
import core.Person;
import dataBase.DbHolder;

public class ArcherDbEditorController implements Observer {

	public ArcherDbEditorController() {
		DbHolder.getInstance().getArcherData().addObserver(this);
	}

	public void filloutForm() throws IndexOutOfBoundsException {

		int row = ArcherDbEditor.getInstance().getDbView().convertRowIndexToModel(ArcherDbEditor.getInstance().getDbView().getSelectedRow());

		ArcherDbEditor.getInstance().getNameTextBox().setText(ArcherDbEditor.getInstance().getDbView().getModel().getValueAt(row, 1).toString());
		ArcherDbEditor.getInstance().getSurNameTextBox().setText(ArcherDbEditor.getInstance().getDbView().getModel().getValueAt(row, 2).toString());
		ArcherDbEditor.getInstance().getNationDropDown()
				.setSelectedIndex(this.getMatchingDropDownIndex(ArcherDbEditor.getInstance().getNationDropDown(), ArcherDbEditor.getInstance().getDbView().getModel().getValueAt(row, 3).toString()));
		ArcherDbEditor.getInstance().getCountryDropDown()
				.setSelectedIndex(this.getMatchingDropDownIndex(ArcherDbEditor.getInstance().getCountryDropDown(), ArcherDbEditor.getInstance().getDbView().getModel().getValueAt(row, 4).toString()));
		ArcherDbEditor
				.getInstance()
				.getBowCathegoryDropDown()
				.setSelectedIndex(
						this.getMatchingDropDownIndex(ArcherDbEditor.getInstance().getBowCathegoryDropDown(), ArcherDbEditor.getInstance().getDbView().getModel().getValueAt(row, 5).toString()));
		ArcherDbEditor.getInstance().getAgeClassDropDown()
				.setSelectedIndex(this.getMatchingDropDownIndex(ArcherDbEditor.getInstance().getAgeClassDropDown(), ArcherDbEditor.getInstance().getDbView().getModel().getValueAt(row, 6).toString()));
		ArcherDbEditor.getInstance().getClubDropDown()
				.setSelectedIndex(this.getMatchingDropDownIndex(ArcherDbEditor.getInstance().getClubDropDown(), ArcherDbEditor.getInstance().getDbView().getModel().getValueAt(row, 7).toString()));
		ArcherDbEditor.getInstance().getGenderDropDown()
				.setSelectedIndex(this.getMatchingDropDownIndex(ArcherDbEditor.getInstance().getGenderDropDown(), ArcherDbEditor.getInstance().getDbView().getModel().getValueAt(row, 8).toString()));
		ArcherDbEditor.getInstance().getLicenseCheckBox().setSelected(new Boolean(ArcherDbEditor.getInstance().getDbView().getModel().getValueAt(row, 9).toString()));
		ArcherDbEditor.getInstance().getCountryRatingCheckBox().setSelected(new Boolean(ArcherDbEditor.getInstance().getDbView().getModel().getValueAt(row, 10).toString()));
		ArcherDbEditor.getInstance().getBirthdateTextBox().setText(ArcherDbEditor.getInstance().getDbView().getModel().getValueAt(row, 11).toString());

		this.updateAgeInformation(new Date(ArcherDbEditor.getInstance().getBirthdateTextBox().getText()));
	}

	public void updateAgeInformation(Date birthDate) {

		int age = Date.getAge(birthDate);

		if ((age < 100) && !birthDate.equals(new Date("blubb"))) { // blubb
			// generates
			// error
			// date...
			ArcherDbEditor.getInstance().getComputedAgeLabel().setText(new Integer(age).toString());
		} else {
			ArcherDbEditor.getInstance().getComputedAgeLabel().setText("-");
		}
	}

	private int getMatchingDropDownIndex(JComboBox combobox, String toMatch) {
		for (int i = 0; i < combobox.getItemCount(); i++) {
			if (combobox.getItemAt(i).toString().equals(toMatch)) {
				return i;
			}
		}
		return 0;
	}

	private ComboBoxModel comboBoxModelFactory(Object [] content) {
		return new DefaultComboBoxModel(content);
	}

	public void setDropDownMenus() {
		String [] nations = DbHolder.getInstance().getArcherData().getAllNations();
		java.util.Arrays.sort(nations);
		ArcherDbEditor.getInstance().getNationDropDown().setModel(this.comboBoxModelFactory(nations));

		String [] countries = DbHolder.getInstance().getArcherData().getAllCountries();
		java.util.Arrays.sort(countries);
		ArcherDbEditor.getInstance().getCountryDropDown().setModel(this.comboBoxModelFactory(countries));

		String [] bowCathegories = DbHolder.getInstance().getArcherData().getAllBowCathegories();
		java.util.Arrays.sort(bowCathegories);
		ArcherDbEditor.getInstance().getBowCathegoryDropDown().setModel(this.comboBoxModelFactory(bowCathegories));

		String [] ageClasses = DbHolder.getInstance().getArcherData().getAllAgeClasses();
		java.util.Arrays.sort(ageClasses);
		ArcherDbEditor.getInstance().getAgeClassDropDown().setModel(this.comboBoxModelFactory(ageClasses));

		String [] clubs = DbHolder.getInstance().getArcherData().getAllClubs();
		java.util.Arrays.sort(clubs);
		ArcherDbEditor.getInstance().getClubDropDown().setModel(this.comboBoxModelFactory(clubs));

		ArcherDbEditor.getInstance().getGenderDropDown().setModel(this.comboBoxModelFactory(new String [] { Constants.MALE, Constants.FEMALE }));
	}

	public void saveButtonAction() {
		this.saveEntry();
	}

	public void saveEntry() {
		boolean error = false;

		String name;
		String surName;
		String nation;
		String country;
		String bowCathegory;
		String ageClass;
		String club;
		String gender;
		boolean license;
		boolean countryRating;
		String birthDate;

		error = CorrectnessTester.testCorrectness(error, (name = ArcherDbEditor.getInstance().getNameTextBox().getText()).isEmpty(), ArcherDbEditor.getInstance().getNameLabel());
		error = CorrectnessTester.testCorrectness(error, (surName = ArcherDbEditor.getInstance().getSurNameTextBox().getText()).isEmpty(), ArcherDbEditor.getInstance().getSurNameLabel());
		error = CorrectnessTester.testCorrectness(error, (nation = ArcherDbEditor.getInstance().getNationDropDown().getSelectedItem().toString()).isEmpty(), ArcherDbEditor.getInstance()
				.getNationLabel());
		error = CorrectnessTester.testCorrectness(error, (country = ArcherDbEditor.getInstance().getCountryDropDown().getSelectedItem().toString()).isEmpty(), ArcherDbEditor.getInstance()
				.getCountryLabel());
		error = CorrectnessTester.testCorrectness(error, (bowCathegory = ArcherDbEditor.getInstance().getBowCathegoryDropDown().getSelectedItem().toString()).isEmpty(), ArcherDbEditor.getInstance()
				.getBowCathegoryLabel());
		error = CorrectnessTester.testCorrectness(error, (ageClass = ArcherDbEditor.getInstance().getAgeClassDropDown().getSelectedItem().toString()).isEmpty(), ArcherDbEditor.getInstance()
				.getAgeClassLabel());
		error = CorrectnessTester.testCorrectness(error, (club = ArcherDbEditor.getInstance().getClubDropDown().getSelectedItem().toString()).isEmpty(), ArcherDbEditor.getInstance().getClubLabel());

		gender = ArcherDbEditor.getInstance().getGenderDropDown().getSelectedItem().toString();
		license = ArcherDbEditor.getInstance().getLicenseCheckBox().isSelected();
		countryRating = ArcherDbEditor.getInstance().getCountryRatingCheckBox().isSelected();
		birthDate = new Date(ArcherDbEditor.getInstance().getBirthdateTextBox().getText()).toString();

		if (!error) {
			int modelRow = ArcherDbEditor.getInstance().getDbView().convertRowIndexToModel(ArcherDbEditor.getInstance().getDbView().getSelectedRow());
			int row = ArcherDbEditor.getInstance().getDbView().getSelectedRow();
			int playerID = Integer.parseInt(((ArcherDBTableModel) ArcherDbEditor.getInstance().getDbView().getModel()).getValueAt(modelRow, 0).toString());
			Person updatedPerson = new Person(name, surName, nation, country, bowCathegory, ageClass, club, gender, license, countryRating, birthDate);
			try {
				DbHolder.getInstance().getArcherData().update(playerID, updatedPerson); // save
				// changes
				// to
				// DB
				((ArcherDBTableModel) ArcherDbEditor.getInstance().getDbView().getModel()).replaceRow(modelRow, updatedPerson.toArrayPlusID(playerID)); // update
				// table
				this.setDropDownMenus(); // update dropdown
				// menus
				ArcherDbEditor.getInstance().getDbView().setRowSelectionInterval(row, row); // select
				// same
				// row as before
				this.filloutForm(); // refill form so that correct
				// dropdown
				// entries are selected
				InformationDisplay saveInformation = new InformationDisplay(ArcherDbEditor.getInstance().getInformationLabel(), "Eintrag gespeichert", Color.green, 2000);
				saveInformation.start(); // display the "saved-information"
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public void buildTable() throws SQLException {
		ArcherDBTableModel model = new ArcherDBTableModel(new String [] { GuiComponentLabels.ID, GuiComponentLabels.NAME, GuiComponentLabels.SURNAME, GuiComponentLabels.NATION,
				GuiComponentLabels.COUNTRY, GuiComponentLabels.BOW_CATHEGORY, GuiComponentLabels.AGE_CLASS, GuiComponentLabels.CLUB, GuiComponentLabels.GENDER, GuiComponentLabels.LICENSE,
				GuiComponentLabels.COUNTRY_RATING, GuiComponentLabels.BIRTHDATE });
		Person [] allArchers = DbHolder.getInstance().getArcherData().getAllArchersInDBQuick();
		for (int i = 0; i < allArchers.length; i++) {
			if (allArchers [i] != null) {
				model.addRow(allArchers [i].toArrayPlusID(i));
			}
		}
		ArcherDbEditor.getInstance().getDbView().setModel(model);
		model.setBowCathegoryColumnIndex(5);
		model.setAgeClassColumnIndex(6);
		model.setGenderColumnIndex(8);
		ArcherDbEditor.getInstance().getDbView().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	}

	public void setRowSelected(int playerID) {
		int rowIndexToFocus = 0;
		for (int i = 0; i < ArcherDbEditor.getInstance().getDbView().getRowCount(); i++) {
			if (ArcherDbEditor.getInstance().getDbView().getValueAt(i, 0).equals(playerID)) {
				rowIndexToFocus = i;
				break;
			}
		}
		ArcherDbEditor.getInstance().getDbView().setRowSelectionInterval(rowIndexToFocus, rowIndexToFocus);
	}

	@Override
	public void update(Observable arg0, Object arg1) {
		try {
			this.buildTable();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void addArcher() {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				AddArcherWindow.getInstance().setLocationRelativeTo(null);
				AddArcherWindow.getInstance().setVisible(true);
				AddArcherWindow.getInstance().getController().setDropDownMenus();
			}
		});
	}

	public void setPlayerSelected(int playerID) {
		for (int i = 0; i < ArcherDbEditor.getInstance().getDbView().getRowCount(); i++) {
			if (Integer.parseInt(ArcherDbEditor.getInstance().getDbView().getValueAt(i, 0).toString()) == playerID) {
				ArcherDbEditor.getInstance().getDbView().setRowSelectionInterval(i, i);
				break;
			}
		}
	}
}
